#!/usr/bin/env node

/**
 * SVG 图标组件生成器
 *
 * 转换 SVG 图标为 inline 数据
 *
 */

const fs = require("fs");
const path = require("path");

const root = path.resolve(__dirname + "/../../..");
const svgo = root + "/svgo.config.js";
if (!fs.existsSync(svgo)) {
  fs.copyFileSync(__dirname + "/svgo.config.js", svgo);
}

const { optimize } = require("svgo");

// 需要处理的颜色属性
let svgBase = "";

if (fs.existsSync(root + "/src")) {
  svgBase = root + "/src/static";
} else {
  svgBase = root + "/static";
}
const svgFolder = svgBase + "/svg-icons";

if (!fs.existsSync(svgFolder)) {
  fs.mkdirSync(svgFolder, { recursive: true });
}
const svgLibFile = svgBase + "/svg-icons-lib.js";

const svgLibCurrent = (() => {
  try {
    let raw = fs.readFileSync(svgLibFile, { encoding: "utf-8" });
    raw = raw.substring(raw.indexOf("export default") + 15);
    return JSON.parse(raw).icons;
  } catch (err) {}
  return {};
})();
const svgPath = path.resolve(svgFolder);
const svgLib = {};
const svgList = fs.readdirSync(svgPath);
const reg = /\.svg$/i;

const palette = [];
const strokeWarn = [];

svgList.forEach((item) => {
  if (!reg.test(item)) return;

  const name = item.slice(0, -4);
  let svgContent = fs.readFileSync(svgPath + "/" + item);
  // svgo 会过滤纯黑, 此处对纯黑做简单处理
  svgContent = (svgContent.toString()).replace(/#0{3,8}/g, '#000001').replace(/rgb\(0, *0, *0\)/gi, 'rgb(0,0,0.0039)')
  const result = optimize(svgContent, {
    multipass: true,
  });

  svgLib[name] = result.data;

  // fill, stroke 等
  const regColorProps = /(fill|stroke|class|style)="([^"]+)"/g;
  let colors = [...result.data.matchAll(regColorProps)]
    .map((item) => {
      if (item[2] === "none") return false;

      let color = item[2];

      if (item[1] === "class") {
        const clspos = result.data.indexOf(`.${item[2]}[,{]`);
        const clsend = result.data.indexOf("}", clspos);
        const clrpos = result.data.indexOf("fill:", clspos);
        if (clrpos < clsend) {
          const str = result.data.substring(clrpos, clrpos + 40)
          const matched = str.match(/fill:((?:rgba?|hsla?)\([\d,.]+\)|#[a-f0-9]+)/i)
          if (matched && matched.length)
            color = matched[0].substring(5)
        } else {
          color = false
        }
      } else if (item[1] === "style") {
        const matched = item[2].match(/fill:((?:rgba?|hsla?)\([\d,.]+\)|#[a-f0-9]+)/i)
        if (matched && matched.length) {
          color = matched[0].substring(5)
        } else {
          color = false;
        }
      } else if (item[1] === "fill") {
        if (/^url/i.test(item[2])) color = false;
      }

      if (color) {
        color = color.toLowerCase();

        if (!palette.includes(color)) {
          palette.push(color);
        }
      }

      return color;
    })
    .filter((item) => !!item);
  // 渐变颜色
  //  <stop offset="0.36" stop-color="#ee2a7b"/>
  //  <stop offset="0" style="stop-color:#000000;stop-opacity:0.1"/>
  const regColorGradient =
    /(stop-color|style)="[^" ]*(?:stop-color:)?(#[0-9a-f]{3,8})"/g;
  const gradientColors = [...result.data.matchAll(regColorGradient)].map(
    (item) => {
      if (!palette.includes(item[2])) palette.push(item[2]);
      return item[2];
    }
  );
  colors.push(...gradientColors);
  colors = Array.from(new Set(colors));
  const colorMap = colors.map((c) => palette.indexOf(c));
  const colorTotal = colors.length;

  console.log(name)
  if (colorTotal === 0) {
    console.log("    ", "!!! 图标没有颜色定义, 将不支持改色. !!!");
  } else if (colorTotal > 0) {
    console.log("    ", colors);
  }

  if (/stroke(?:-width)?="/i.test(result.data)) {
    strokeWarn.push(name);
  }

  svgLib[name] = [result.data, ...colorMap];
});

if (strokeWarn.length) {
  console.log(
    "\n以下图标含有描边, 在缩放时可能导致非预期效果。建议将描边全部转换为填充。"
  );
  console.log("\n", strokeWarn.join(", "), "\n");
}


const data = {
  icons: JSON.parse(JSON.stringify(svgLib)),
  $_colorPalette: palette,
};


const hasChange = JSON.stringify(svgLibCurrent) !== JSON.stringify(data)
if (hasChange) {
  const script = [
    `/**
 *
 * Icon Library for <zui-svg-icon> usage
 *
 * Auto generated by /tools/svgicon.js
 *
 * !!! DO NOT MODIFY MANUALLY !!!
 *
 * @datetime ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}
 *
 */`,
    "",
    "export default " + JSON.stringify(data, null, 2),
  ];
  fs.writeFileSync(svgLibFile, script.join("\n"));
  console.log(
    `\nTotal ${
      Object.keys(svgLib).length
    } svg icon(s) generated.`
  );
} else {
  console.log(
    `\nTotal ${Object.keys(svgLib).length} svg icon(s) generated, nochange.`
  );
}
